================================================================================
  PhizmOsc Transwave Engine Manual
  A 2-Oscillator Transwave Synthesizer
================================================================================

  "Transwave" synthesis, as pioneered by the Ensoniq and popularized by their 
  Fizmo synthesizer, is built around the idea of a wavetable that gets scanned
  through over time, frame by frame, according to, in he case of PhizmOsc, a
  drawn curve - not swept with a simple LFO. Each oscillator morphs through its
  wavetable at a rate and trajectory the user can design. The two oscillators
  share a single scan clock but can follow completely different curve shapes,
  so their timbres evolve in lockstep but diverge in character.

  HOW TO INSTALL:
	Simply move the .vst3 folder to C:/Program Files/Common Files/VST3.
	The .exe can be run from anywhere, no install needed.

================================================================================
  TITLE BAR
================================================================================

  INTERP
      	Frame interpolation. When ON (default), the engine uses bilinear
      	interpolation both between adjacent wavetable frames and within each
      	cycle. Turn OFF for a slightly rougher, more hardware-like texture.

  PV FILT
      	Per-Voice Filter. When OFF (default), a single global 4-pole lowpass
      	filter processes the summed output of all voices, fast and cheap.
      	When ON, every voice gets its own independent filter instance, so
      	each note's filter envelope runs completely separately. Chords bloom
      	and decay at their own pace. Costs more CPU with many voices.

  VEL>FRM
	Velocity to Frame Position. When ON, harder playing offsets the
      	starting frame position into the wavetable. A soft note starts at
      	the beginning of the evolution curve and a hard note starts further in.
      	Creates expressive, touch-sensitive timbre changes.

  EVO CARRY
      	Evolution Phase Carry. When OFF (default), each new note resets its
      	scan position to the start of the evolution curve. When ON, a new
      	note inherits the current scan position from the most recently active
      	voice - the evolution never resets, it simply keeps moving regardless
      	of note triggers. Great for pads and long evolving textures.

  Preset Section
      	Shows the name of the currently loaded preset, or "- init -" for
      	a fresh state.

  LOAD / SAVE
      	Load or save a .phism preset file. Presets store all knob positions,
      	evolution curves, and wavetable file paths. The .wav samples themselves
      	are not embedded - they are reloaded from their original location.

================================================================================
  WAVETABLE SECTION
================================================================================

  Gain
      	Master output level multiplicator.

================================================================================
  EVOLUTION SECTION
================================================================================

  The evolution engine is the heart of the synth. It scans through the
  wavetable over time by reading a position from a curve you draw in the
  curve editors (right column). The scan clock is shared between the two
  oscillators, but each reads from its own independent curve shape.

  Evo Time
      	How long one full pass through the evolution curve takes, in seconds
      	(0.1s – 100s). Short times produce fast, rhythmic timbral movement.
      	Long times produce slow, almost static morphs. Interacts with Scan Dir.

  Evo LFO Hz
      	Rate of the LFO that modulates the scan position on top of the curve.
      	Per-voice, with a small random phase offset per note to keep chords alive.

  Evo LFO Dpt
      	Depth of the scan-position LFO. At zero, pure curve scanning. Higher
      	values add a wobble around the curve's output, widening the morph range.

  Pos LFO Hz
      	Rate of a second LFO that is also added to the frame position. This one
      	is used simultaneously as the filter LFO modulator (see Filter section).

  Pos LFO Dpt
      	Depth of the position LFO. Blends with the Evo LFO for complex motion.

================================================================================
  PITCH SECTION
================================================================================

  Detune ct
      	Global coarse/fine detune in cents (–100 to +100). Shifts both
      	oscillators together.

  Pitch LFO
      	Depth of the pitch LFO in semitones (0–12st). The pitch LFO is global,
      	shared across all voices.

  Pitch LFO Hz	Rate of the pitch LFO (0.01 - 20 Hz).

  P. Env Amt
      	Pitch envelope amount in semitones (–24 to +24). Positive values give
      	each note a bright upward attack, negative values give a downward dip.

  P. Env Att
      	Attack time of the pitch envelope (the time from note-on to reach
      	full pitch offset).

  P. Env Dec
      	Decay time of the pitch envelope back to zero (the pitch envelope has
      	no sustain - it always decays fully to zero after the attack).

================================================================================
  OSC 1, 2 ENVELOPE
================================================================================

  Controls the amplitude of Oscillator A (wavetable slot A) and Oscillator B.
  Use different values for Oscillator A and B for swelling effects.
  
  Osc 1, 2 Att    Attack time (0.001s – 8s)
  Osc 1, 2 Dec    Decay time down to the sustain level
  Osc 1, 2 Sus    Sustain level (0.0 – 1.0)
  Osc 1, 2 Rel    Release time after note-off

================================================================================
  CHARACTER SECTION
================================================================================

  Bit Depth
      	Bit-crusher. At 16 (maximum), no crushing is applied. Lower values
      	reduce the amplitude resolution of each wavetable sample, adding
      	classic digital harshness. At 4, it is the most lo-fi, but still subtle.

  Grit
      	Quantises the oscillator's playback phase into coarser steps, reducing
      	the number of distinct sample positions the oscillator can land on per
      	cycle. At zero, full resolution. At maximum, as few as 6 steps per
      	cycle - the characteristic stair-stepped Transwave clanginess.
      	effect is cubic: the first 30% of the knob is subtle vintage texture,
      	the rest is increasingly extreme.

================================================================================
  SCAN SECTION
================================================================================

  Scan Dir
      	The direction the scan clock moves through the evolution curve:
        0 - Forward         Loops continuously forward, wraps around
        1 - Fwd Stay        Scans forward once, then holds at the end
        2 - Back & Forth    Ping-pong, reverses at each end
        3 - Bwd Stay        Scans backward once, then holds at the start
        4 - Backward        Loops continuously backward, wraps around

  Rnd Jump
      	Random frame jump probability. Each time Osc A completes a full cycle,
      	there is a chance (scaled by this knob) of the frame position making
      	a random jump. Creates stuttering, glitchy transwave leaps. Applies to
      	both oscillators simultaneously. For pleasant sounds, use very low values.

================================================================================
  FILTER SECTION
================================================================================

  The filter is a 4-pole (24 dB/oct) lowpass filter. In global mode (where the
  PV FILT toggle is off) it processes the summed mix. In per-voice mode it is
  applied independently to each voice before summing.

  Cutoff       Filter cutoff frequency (20 Hz – 20 kHz).

  Resonance    
	Filter Q / resonance (0.1 – 12). Above ~3 the filter self-
        oscillates at high input levels.

  F. Env Amt   
	Amount of the filter envelope applied to the cutoff, in octaves
        (–1 to +1). Negative values make the filter close on attack.
               
  F. LFO       Depth of the Pos LFO applied to the filter cutoff.

================================================================================
  OCTAVE SECTION
================================================================================

  Oct Osc 1    Octave transpose for Oscillator A (–2 to +2 octaves, integers).
  Oct Osc 2    Octave transpose for Oscillator B (–2 to +2 octaves, integers).

  Transposing the oscillators independently is a classic transwave technique:
  put Osc B two octaves down for a simultaneous high/low morph texture.

================================================================================
  GLIDE SECTION
================================================================================

  Glide        
	Portamento time (0–4s). Pitch slides in log space (perceptually
        linear), so the glide duration feels consistent across intervals.
        Glide only works in Mono mode.

  Mono         
	Mono mode on/off. When on, the synth is monophonic - all new
        notes steal voice 0, with glide applied from the previous pitch.

================================================================================
  FILTER ENVELOPE SECTION
================================================================================

  A separate ADSR that modulates the filter cutoff. Its depth is set by
  F. Env Amt in the Filter section.

  F. Att       Filter envelope attack
  F. Dec       Filter envelope decay
  F. Sus       Filter envelope sustain level
  F. Rel       Filter envelope release

================================================================================
  STEREO SECTION
================================================================================

  Spread ct    
	Detunes the two oscillators apart in opposite directions   
	(0–50 cents) to create natural stereo width from pitch
        difference between Osc A and Osc B.

  Width        
	Stereo width of each individual oscillator. Each oscillator
	generates two slightly phase-offset readings of its wavetable
	and applies mid-side widening between them.

  Uni Detune   
	Unison detune. Adds a per-voice random detune amount (0–50 cents).
	Each voice gets a consistent random offset determined
	by its MIDI note number. Thickens chords.

  B Phase      
	Phase offset for Oscillator B's wavetable read position
	(0.0–1.0 cycles). Shifts Osc B's cycle start point relative
	to Osc A, affecting the stereo cancellation/reinforcement
	between them.

  A/B Mix      
	Crossfade between Oscillator A and Oscillator B (0 = full A,
	1 = full B). The wavetable display highlights the dominant
	oscillator. Each oscillator applies its own amplitude envelope
	at its own level before this mix is applied.
	This is probably the most important knob for dialing in character.

================================================================================
  FX SECTION
================================================================================

  Chr Rate     Chorus LFO rate (0.01–8 Hz).
  Chr Depth    
	Chorus depth. At zero, chorus is bypassed entirely.
	The chorus is a stereo dual-delay modulated by opposing LFO
	phases for a wide, natural spread.

  Ring Mod     
	Ring modulation between Osc A and Osc B. At zero, bypassed.
	At maximum, pure amplitude multiplication between the two
	oscillators. Intermediate values crossfade between dry and
	ring-modulated signal with amplitude compensation so level
	stays consistent.

  Rvb Size     Reverb room size (Juce Reverb, 0–1).
  Rvb Damp     Reverb high-frequency damping.
  Rvb Wet      Reverb wet/dry mix. At zero, reverb is effectively off.

  Noise        
	White noise level, mixed pre-filter so the noise gets shaped
	by the filter envelope. Useful for breath, wind, and percussive
	transients.

================================================================================
  EVOLUTION CURVE EDITORS  (right column)
================================================================================

  Two identical curve editors - one for Osc A (top), one for Osc B (bottom).
  Each has 32 draggable control points. The curve maps scan time (x-axis,
  0–1) to wavetable frame position (y-axis, 0–1). The two oscillators share
  a single scan clock but each reads from its own curve, so they can morph
  through their wavetables in completely different ways at the same pace.

  Drawing
      	Click and drag anywhere in the curve area to set control points.
      	Drag left/right to move between points, up/down to set height.

  Playhead
      	The glowing dot moving along the curve shows the current scan position
      	of the active voice in real time. The vertical white line shows
      	the scan position across the full width.

  FLAT
      	Resets all 32 curve points to 0.5 (centre). The frame position stays
      	fixed at the middle of the wavetable - no morphing.

  RAMP
      	Sets the curve to a linear ramp from 0 to 1. This is the simplest
      	forward morph: the oscillator scans through its entire wavetable
      	over one Evo Time period.

  STEP
      	Toggles stepped (sample-and-hold) vs. smooth (linear interpolated)
      	reading of the curve. In STEP mode the curve holds each point value
      	as a flat step until the next point, producing abrupt frame jumps.
      	In smooth mode, point values are linearly interpolated between nodes.
      	STEP is shown highlighted when active and produces nice blip sounds.

================================================================================
  WAVETABLE LOADING  (bottom strip)
================================================================================

  LOAD A / LOAD B
      	Opens a file browser to load a .wav file as the wavetable for
      	slot A or slot B respectively. Any mono .wav works. Multi-cycle
      	wavetable files (where one file contains many single-cycle waveforms
      	concatenated) are fully supported.
      	mp3 is not supported as it usually has encoder padding silence, which is
      	bad for using them as wavetables.

  Cycle:
      	The number of samples per single cycle in the loaded file. Default
      	is 2048. Common values: 256, 512, 1024, 2048. Set this before (or
      	re-enter it after) loading if the auto-detected frame count looks
      	wrong. The engine divides the total file length by this number to
      	determine the number of frames.

  Filename display
      	Shows the name of the currently loaded .wav file for each slot.

  Wavetable displays
      	The animated waveform at the bottom shows the current frame being
      	read by each oscillator, updated in real time as the evolution curve
      	scans. The display is highlighted when that oscillator is dominant
      	in the A/B Mix.

================================================================================
  ACKNOWLEDGEMENTS
================================================================================
	
	PhizmOsc is inspired by the Ensoniq Fizmo Synth but not a copy of it.
	It is named PhizmOsc as it is rather a simple 2-Osc reimagination of
	a transwave synthesizer rather than a full product.

	PhizmOsc was, for the most parts at least, coded using Claude.ai
	and the Sonnet 4.6, medium effort, no thinking model.

	Feel free to do anything with the code you like, except selling it
	for profit. Feel free use it in your projects, but please keep it 	
	open source. The provided source code is for the JUCE platform.